if(LLVM_ENABLE_PGO STREQUAL "GEN")
    set(llvm_pgo "-fprofile-generate=${LLVM_PROFILE_DATA_DIR} -fprofile-update=atomic -mllvm -vp-counters-per-site=64")
elseif(LLVM_ENABLE_PGO STREQUAL "CSGEN")
    set(llvm_pgo "-fcs-profile-generate=${LLVM_PROFILE_DATA_DIR} -fprofile-update=atomic -mllvm -vp-counters-per-site=64 -fprofile-use=${LLVM_PROFDATA_FILE}")
elseif(LLVM_ENABLE_PGO STREQUAL "USE")
    set(llvm_pgo "-fprofile-use=${LLVM_PROFDATA_FILE}")
endif()
include(CheckCCompilerFlag)
check_c_compiler_flag("-mtls-dialect=gnu2" TLSDESC_AVAILABLE)
check_c_compiler_flag("-Wa,-msse2avx" SSE2AVX_AVAILABLE)
check_c_compiler_flag("-mllvm -polly -mllvm -polly-annotate-metadata-vectorize" POLLY_AVAILABLE)
set(tc_cflags "-Wno-unused-command-line-argument -g0 -fno-ident -fno-temp-file -fPIC -fno-plt -Wa,--crel,--allow-experimental-crel -fdata-sections -ffunction-sections -fseparate-named-sections -fno-unique-section-names -fno-semantic-interposition -fvisibility=hidden -fstrict-flex-arrays=3 -march=native -O3 -funroll-loops -fno-signed-zeros -fno-trapping-math -mrecip=all -freciprocal-math -fapprox-func -ffp-contract=fast -fno-math-errno -falign-functions=32 -ftls-model=local-exec -fno-unwind-tables -fno-asynchronous-unwind-tables -fsized-deallocation -fnew-infallible -faligned-allocation -Xclang -mlong-double-64 -UHAS_80_BIT_LONG_DOUBLE -DHAS_80_BIT_LONG_DOUBLE=0 -mllvm -enable-vtable-value-profiling -mllvm -enable-vtable-profile-use")
set(tc_ldflags "-fuse-ld=lld -flto-jobs=${MAKEJOBS} -Wl,--lto-whole-program-visibility,-Bsymbolic,--build-id=none,-O3,--lto-O3,--lto-CGO3,--icf=all,--gc-sections,-znow,-zrodynamic,-zpack-relative-relocs,-zcommon-page-size=2097152,-zmax-page-size=2097152,-zseparate-loadable-segments,-zkeep-text-section-prefix,-zstart-stop-visibility=hidden,-mllvm,-enable-vtable-value-profiling,-mllvm,-enable-vtable-profile-use,-mllvm,-import-instr-limit=175,-mllvm,-import-hot-multiplier=2")
if(TLSDESC_AVAILABLE)
    set(tc_cflags "${tc_cflags} -mtls-dialect=gnu2")
endif()
if(SSE2AVX_AVAILABLE)
    set(tc_cflags "${tc_cflags} -Wa,-msse2avx -mno-vzeroupper")
endif()
set(polly "-mllvm -polly -mllvm -polly-vectorizer=stripmine -mllvm -polly-optimizer=isl -mllvm -polly-position=before-vectorizer -mllvm -polly-loopfusion-greedy -mllvm -polly-2nd-level-tiling -mllvm -polly-register-tiling -mllvm -polly-tc-opt -mllvm -polly-run-dce -mllvm -polly-annotate-metadata-vectorize")
set(polly_lto "-Wl,-mllvm,-polly,-mllvm,-polly-vectorizer=stripmine,-mllvm,-polly-optimizer=isl,-mllvm,-polly-position=before-vectorizer,-mllvm,-polly-loopfusion-greedy,-mllvm,-polly-2nd-level-tiling,-mllvm,-polly-register-tiling,-mllvm,-polly-tc-opt,-mllvm,-polly-run-dce,-mllvm,-polly-annotate-metadata-vectorize")
if(POLLY_AVAILABLE)
   set(tc_polly "${polly}")
   set(tc_polly_lto "${polly_lto}")
endif()
set(llvm_mllvm "-mllvm -enable-masked-interleaved-mem-accesses -mllvm -enable-interleaved-mem-accesses -mllvm -enable-cond-stores-vec -mllvm -slp-vectorize-hor-store")
set(llvm_mllvm "${llvm_mllvm} -mllvm -enable-loopinterchange -mllvm -enable-loop-distribute -mllvm -enable-unroll-and-jam -mllvm -allow-unroll-and-jam -mllvm -enable-loop-flatten -mllvm -unroll-runtime-multi-exit -mllvm -aggressive-ext-opt")
set(llvm_mllvm "${llvm_mllvm} -mllvm -adce-remove-loops -mllvm -enable-ext-tsp-block-placement -mllvm -enable-gvn-hoist -mllvm -enable-gvn-sink=false -mllvm -sink-common-insts=false -mllvm -vectorizer-maximize-bandwidth -mllvm -combiner-global-alias-analysis -mllvm -optimize-regalloc -mllvm -misched-postra -mllvm -gc-empty-basic-blocks -mllvm -enable-merge-functions -mllvm -mergefunc-use-aliases -mllvm -enable-jump-table-to-switch -mllvm -enable-loop-flatten -mllvm -enable-early-exit-vectorization -mllvm -enable-loop-versioning-licm -mllvm -slp-revec -mllvm -slp-vectorize-non-power-of-2 -mllvm -enable-memcpyopt-without-libcalls -mllvm -pgso=false -mllvm -enable-ipra")
set(llvm_mllvm_lto "-Wl,-mllvm,-disable-auto-upgrade-debug-info,-mllvm,-enable-masked-interleaved-mem-accesses,-mllvm,-enable-interleaved-mem-accesses,-mllvm,-enable-cond-stores-vec,-mllvm,-slp-vectorize-hor-store")
set(llvm_mllvm_lto "${llvm_mllvm_lto} -Wl,-mllvm,-enable-loopinterchange,-mllvm,-enable-loop-distribute,-mllvm,-enable-unroll-and-jam,-mllvm,-allow-unroll-and-jam,-mllvm,-enable-loop-flatten,-mllvm,-unroll-runtime-multi-exit,-mllvm,-aggressive-ext-opt")
set(llvm_mllvm_lto "${llvm_mllvm_lto} -Wl,-mllvm,-adce-remove-loops,-mllvm,-enable-ext-tsp-block-placement,-mllvm,-enable-gvn-hoist,-mllvm,-enable-gvn-sink=false,-mllvm,-sink-common-insts=false,-mllvm,-vectorizer-maximize-bandwidth,-mllvm,-combiner-global-alias-analysis,-mllvm,-optimize-regalloc,-mllvm,-misched-postra,-mllvm,-gc-empty-basic-blocks,-mllvm,-enable-merge-functions,-mllvm,-mergefunc-use-aliases,-mllvm,-enable-jump-table-to-switch,-mllvm,-enable-loop-flatten,-mllvm,-enable-early-exit-vectorization,-mllvm,-enable-loop-versioning-licm,-mllvm,-slp-revec,-mllvm,-slp-vectorize-non-power-of-2,-mllvm,-enable-memcpyopt-without-libcalls,-mllvm,-pgso=false,-mllvm,-enable-ipra")
if(LLVM_ENABLE_LTO STREQUAL "Thin")
    set(tc_cflags "${tc_cflags} -flto=thin -fwhole-program-vtables -fstrict-vtable-pointers -fsplit-lto-unit")
    set(tc_ldflags "${tc_ldflags} ${llvm_mllvm_lto} ${tc_polly_lto}")
    check_c_compiler_flag("-funique-source-file-names" UNIQUE_SOURCE_FILE_NAMES_AVAILABLE)
    if(UNIQUE_SOURCE_FILE_NAMES_AVAILABLE)
        set(tc_cflags "${tc_cflags} -funique-source-file-names")
    endif()
elseif(LLVM_ENABLE_LTO STREQUAL "Full")
    set(tc_cflags "${tc_cflags} -flto=full -fwhole-program-vtables -fstrict-vtable-pointers -fsplit-lto-unit")
    set(tc_ldflags "${tc_ldflags} ${llvm_mllvm_lto} ${tc_polly_lto}")
else()
    set(tc_cflags "${tc_cflags} ${llvm_mllvm} ${tc_polly}")
endif()
if(TOOLCHAIN_FLAGS)
    set(tc_cflags "${tc_cflags} ${TOOLCHAIN_FLAGS}")
endif()
if(CUSTOM_LIBCXX)
    set(tc_libcxx "-cxx-isystem ${CMAKE_INSTALL_PREFIX}/include/${HOST_ARCH}/c++/v1 -stdlib++-isystem ${CMAKE_INSTALL_PREFIX}/include/c++/v1 -L ${CMAKE_INSTALL_PREFIX}/lib/${HOST_ARCH}")
    set(tc_cflags "${tc_cflags} -fexperimental-relative-c++-abi-vtables -fexperimental-library -stdlib=libc++ --unwindlib=libunwind")
endif()

if(CUSTOM_COMPILER_RT)
    set(tc_compiler_rt "-resource-dir=${CMAKE_INSTALL_PREFIX}/lib/clang/${clang_version} -rtlib=compiler-rt")
endif()

if(TARGET_CPU STREQUAL "x86_64")
    set(ld_m_flag "i386pep")
    set(crt_lib "--disable-lib32 --enable-lib64")
elseif(TARGET_CPU STREQUAL "aarch64")
    set(ld_m_flag "arm64pe")
    set(crt_lib "--disable-lib32 --disable-lib64 --enable-libarm64")
endif()

set(cmake_conf_args
    -GNinja
    -DCMAKE_BUILD_TYPE=Release
    -DCMAKE_INSTALL_PREFIX=${MINGW_INSTALL_PREFIX}
    -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_FILE}
    -DBUILD_SHARED_LIBS=OFF
    -DBUILD_TESTING=OFF
    -DCMAKE_C_STANDARD=17
    -DCMAKE_CXX_STANDARD=20
    -DCMAKE_POLICY_VERSION_MINIMUM=3.5
    -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY
)
